/*	Matt Viehdorfer
 *  CS575 - Spring 2012
 *  Project 9 - OpenCL / OpenGL Particle System
 */

// Particle structure
struct particle
{
	float x0, y0, z0;       // starting location
	float vx0, vy0, vz0;    // starting velocity
	float r0, g0, b0;       // starting color
	float t0, t1;           // birth, death time
	float x, y, z;          // current location
	float vx, vy, vz;       // current velocity
	float r, g, b;          // current color
	float Direction;
	float Acceleration;
	float Deceleration;
	float ScaleP;
};

#define A = 1664525;
#define C = 1013904223;
#define M = 4294967296;

float myRandom(unsigned int i, int low, int high, float* random) {
	*random = fmod(((16645 * (*random)) + 10139042), 42949672);
	return ((high - low) * ((*random) / 42949672)) + low;
}
	
float adjustVelocity(unsigned int i, int low, int high, float* random) {
	return ((((((2 * myRandom(i, low, high, random)) + 1) * myRandom(i, low, high, random)) + 1) * 0.005) - (((((2 * myRandom(i, low, high, random)) + 1) * myRandom(i, low, high, random)) + 1) * 0.005))/50;
}
	
float adjustAccel(unsigned int i, int low, int high, float* random) {
	return (((((5 * myRandom(i, low, high, random)) + 5) * myRandom(i, low, high, random)) + 1) * 0.02)/100;
}
	
__kernel void ckParticleFountain(__global float4* vectorXYZ,
									__global float4* velocityXAZD,
									__global float* randomArray) {
	unsigned int x = get_global_id(0);
	float random = randomArray[x];

	vectorXYZ[x].x = vectorXYZ[x].x + velocityXAZD[x].x;
	vectorXYZ[x].y = vectorXYZ[x].y + velocityXAZD[x].y - velocityXAZD[x].w;
	vectorXYZ[x].z = vectorXYZ[x].z + velocityXAZD[x].z;
	velocityXAZD[x].w = velocityXAZD[x].w + 0.0015;
		
	if(vectorXYZ[x].y < -5) {
		vectorXYZ[x].x = 0;
		vectorXYZ[x].y = 0;
		vectorXYZ[x].z = 0;
		velocityXAZD[x].x = adjustVelocity(x, 2, 14, &random);
		velocityXAZD[x].z = adjustVelocity(x, 2, 14, &random);
		velocityXAZD[x].w = 0.0015;
		velocityXAZD[x].y = adjustAccel(x, 2, 11, &random);
	}
		
	randomArray[x] = random;
}